home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
whereis.aqm
/
whereis.asm
Wrap
Assembly Source File
|
1985-09-10
|
16KB
|
510 lines
CG GROUP CODE_SEG
ASSUME CS:CG, DS:CG
; PAGE 101 SOFTALK, JAN 1984
; This pprogram will search all directories for a given filename and print
; the full path name of each one found
; REVISIONS
; The scrolling limitation of 23 lines and the More? prompt with its N key
; exit were added by Ted Eyrick, Eytek, Inc., P.O. Box 160307, San Antonio,
; Texas 78280.
DTA STRUC
; This is the format for the DOS Data Transfer Area used when DOS 2.0
; searches for a file match in directories
RESERVED DB 21 DUP (?)
ATTRIBUTE DB
TIME DW
DATE DW
SIZE DD
NAME_FOUND DB 13 DUP (?)
DTA ENDS
CODE_SEG SEGMENT
; This is the main program that sets up the initial conditions for
; SEARCH_DIRECTORY which, in turn, does a recursive search.
; Reads: PATH_NAME
; Writes: FILE_NAME
; Calls: SEARCH_DIRECTORY
ORG 100H
START:
PUSH AX
MOV AH,30H
INT 21H
CMP AL,2 ; Is it at least 2.0 ?
JAE VERS_OK
MOV DX,OFFSET WRONG_VERS
CALL ERROR
INT 20H
VERS_OK:
MOV AH,19H
INT 21H ; Get the current drive #
MOV [OLDDRIV],AL ; Save it
POP AX
CMP AL,-1 ; Is a valid drive named ?
MOV DX,OFFSET CG:INVALID_DRIVE
JNE TEST_UP
BAD_DRIVE:
CALL ERROR
MOV AL,2 ; Error exit code
JMP DOS_EXIT
TEST_UP:
CMP AH,-1
JE BAD_DRIVE
MOV SI,80H
CMP BYTE PTR[SI],0 ; Any name specified
NO_FILE:
MOV DX,OFFSET CG:NONAME
JE BAD_DRIVE
PARSE_FILE:
MOV DI,65H
MOV CX,3
MOV AL,'?'
REP STOSB ; Put '.*' default
MOV SI,[CMDLINE]
CALL SCANOFF
JNC GOOD_NAME
MOV AL,0
JMP DOS_EXIT
GOOD_NAME:
CMP BYTE PTR[SI],'\' ; Was it a pathname ?
JNE NO_PATH
CALL NEXT_BLANK ; Go to next filename
MOV [CMDLINE],SI ; Ignore pathnames
JMP PARSE_FILE
NO_PATH:
CMP BYTE PTR [FIRST],0
JE FIRST_TIME ; Don't check first time around
FIRST_TIME:
MOV DX,SI
CALL GET_CHAR_COUNT
MOV DI,OFFSET SEARCH_NAME
PUSH SI
REP MOVSB
POP SI
MOV AL,0
STOSB ; Set search name
CALL PRINT_FILE_SEP
MOV DI,5CH
MOV AH,29H
MOV AL,9 ; Ignore leading seps
INT 21H
CMP BYTE PTR[SI],'\' ; Was it a pathname ?
JNE NO_PATH1
CALL NEXT_BLANK ; Go to next filename
MOV [CMDLINE],SI
JMP PARSE_FILE
NO_PATH1:
MOV [CMDLINE],SI ; Save pointer for next time
WHEREIS PROC NEAR
MOV SI,5CH ; FCB
LODSB
CMP AL,0 ; Is it default drive ?
JE IS_DEFAULT
SUB AL,1 ; Convert to logical
MOV DL,AL
MOV [CURDRIVE],AL
MOV AH,0EH
INT 21H ; Select new drive
JMP SHORT SEARCH
IS_DEFAULT:
MOV AL,[OLDDRIV]
MOV [CURDRIVE],AL ; Save it
SEARCH:
MOV DI,OFFSET CG:FILE_NAME
GET_SEARCH_NAME:
CMP SI,65H ; End of FCB name ?
JAE DONE_READING_NAME
LODSB ; get first character
CMP AL,' ' ; Is it space
JE GET_SEARCH_NAME
STOSB
JMP GET_SEARCH_NAME
DONE_READING_NAME:
MOV AL,'.'
STOSB
READ_EXT:
CMP SI,68H ; End of FCB ext ?
JAE FCB_TO_ASCIZ
LODSB
CMP AL,' '
JE READ_EXT
STOSB
JMP READ_EXT
FCB_TO_ASCIZ:
XOR AL,AL ; write a 0 at the end
STOSB
MOV DI,OFFSET CG:PATH_NAME
CMP BYTE PTR[FILE_NAME+1],0 ; Is there a file ?
JNE SEARCH_FILE
MOV AL,0
JMP DOS_EXIT
SEARCH_FILE:
OR AL,AL ; search for the zero at the end
CLD ; of PATH_NAME
MOV CX,64 ; Max. length of scan for 0
REPNZ SCASB
MOV BX,DI
DEC BX
MOV DX,0 ; DS:BX points to end of PATH-NAME
CALL SEARCH_DIRECTORY ; now do the trcursive search
MOV BYTE PTR[FIRST],-1 ; Now we`ll go again !
CALL IS_MORE ; Is there more ?
JAE FINISH
JMP PARSE_FILE
FINISH:
MOV AL,0
JMP DOS_EXIT ; all done now
WHEREIS ENDP
IS_MORE PROC NEAR
; Test to see if more filespecs are on command line
MOV SI,80H
XOR CX,CX
MOV CL,[SI]
MOV DI,81H
ADD DI,CX ; Set DI to end of command line
MOV SI,[CMDLINE]
CMP SI,DI
RET
IS_MORE ENDP
SEARCH_DIRECTORY PROC NEAR
; This procedure searches all the files in the current directory looking for a match.
; It also prints the fill name for each match.
; DS:BX
; DS:DX
; Reads: Disk Transfer Area (DTA)
; Writes: Disk Transfer Area
; Calls: BUILD_NAME, GET_FIRST_MATCH, WRITE_MATCHED_NAME, GET_NEXT_MATCH,
; BUILD_STAR_NAME, SEARCH_SUB_DIRECTORY
PUSH SI ; NEED TO RESTORE ON EXIT
PUSH DX
CALL BUILD_NAME ; Build the absolute search name
CALL GET_FIRST_MATCH ; See if there is a match here
JC NO_MATCH ; no match, check subdirectories
CALL WRITE_MATCHED_NAME ; write name of match
FIND_NEXT_FILE:
CALL GET_NEXT_MATCH ; find the next match
JC NO_MATCH ; no match, search subdirectories
CALL WRITE_MATCHED_NAME ; match, grite absolute name
JMP FIND_NEXT_FILE ; look for the next matching name
NO_MATCH:
POP DX ; restore DTA
PUSH DX
CALL BUILD_STAR_NAME ; search for all directories
CALL GET_FIRST_MATCH ; get first entry
JC NO_MORE_MATCHES ; there are no entries
MOV SI,DX ; put address of DTA into SI
TEST [SI].ATTRIBUTE,10H ; is it a directory entry?
JNZ IS_DIRECTORY ; yes, then search subdirectory
FIND_NEXT_DIRECTORY:
CALL GET_NEXT_MATCH ; no, then find the next match
JC NO_MORE_MATCHES ; there are no more entries
TEST [SI].ATTRIBUTE,10H ; is this a directory?
JZ FIND_NEXT_DIRECTORY ; no, then try again
IS_DIRECTORY:
CMP [SI].NAME_FOUND,'.' ; is this a . or .. directory?
JE FIND_NEXT_DIRECTORY ; yes, skip to next directory
CALL SEARCH_SUB_DIRECTORY ; search the subdirectory
PUSH AX ; now reset the DTA
MOV AH,1AH
INT 21H
POP AX
JMP FIND_NEXT_DIRECTORY
NO_MORE_MATCHES:
POP DX
POP SI
RET
SEARCH_DIRECTORY ENDP
SEARCH_SUB_DIRECTORY PROC NEAR
; This procedure searches the subdirectory whose name is in the DTA
; DS:BX end of the current pathname
; ds:[dx].name_found name of subdirectory for search
; reads: path_name
; writes: path_name
; calls: search_directory
PUSH DI
PUSH SI
PUSH AX
PUSH BX
CLD
MOV SI,DX ; put address of DTA into SI
ADD SI,OFFSET NAME_FOUND ; set to start of subdirectory name
MOV DI,BX
COPY_LOOP:
LODSB
STOSB
OR AL,AL ; was it a 0
JNZ COPY_LOOP ; no, keep copying
MOV BX,DI ;set BX to end of new pathname
STD ; set flag for decrement
STOSB ; store a 0 at end of string
MOV AL,'\'
STOSB ; place '\' at end of pathname
CALL SEARCH_DIRECTORY ; search this new path
POP BX ; restore the old end-of-paht
MOV BYTE PTR [BX],0 ; and store a zero here
POP AX
POP SI
POP DI
RET
SEARCH_SUB_DIRECTORY ENDP
WRITE_MATCHED_NAME PROC NEAR
; This procedure prints the matched name after the path name
PUSH AX
PUSH DX
MOV DL,[CURDRIVE]
ADD DL,'A' ; Convert to ASCII
MOV AH,2
INT 21H
MOV DL,':'
INT 21H
MOV DX,OFFSET CG:PATH_NAME
MOV AL,[BX] ; Save character at end of path
MOV BYTE PTR[BX],0 ; End of string mark
CALL WRITE_STRING
MOV [BX],AL
POP DX
PUSH DX ; Restore old pointer
ADD DX,OFFSET NAME_FOUND
CALL WRITE_STRING
CALL SEND_CRLF
INC LINCTR ;inc line counter
MOV AL,23 ;test for 23 lines printed
CMP AL,LINCTR
JNE WRITEXIT ;no_normal exit
MOV AL,0 ;23 printed, so send
MOV LINCTR,AL ;message
MOV DX,OFFSET CG:PROMPT
MOV AH,9
INT 21H
MOV AH,0
INT 16H
CMP AL,'N'
JE DOS_EXIT
CMP AL,'n'
JE DOS_EXIT
WRITEXIT:
POP DX
POP AX
RET
WRITE_MATCHED_NAME ENDP
BUILD_NAME PROC NEAR
PUSH SI
MOV SI,OFFSET CG:FILE_NAME
CALL BUILD
POP SI
RET
BUILD_NAME ENDP
BUILD_STAR_NAME PROC NEAR
PUSH SI
MOV SI,OFFSET CG:STAR_NAME
CALL BUILD
POP SI
RET
BUILD_STAR_NAME ENDP
BUILD PROC NEAR
PUSH AX
PUSH DI
MOV DI,BX
CLD
COPY_NAME:
LODSB
STOSB ; Get 1 character of name
OR AL,AL ; End of string ?
JNZ COPY_NAME
POP DI
POP AX
RET
BUILD ENDP
GET_FIRST_MATCH PROC NEAR
PUSH CX
CMP DX,0 ; 1st one ?
JA ALLOCATE ; No, then make some space
MOV DX,OFFSET CG:DISK_TRANSFER_AREAS-TYPE DTA
ALLOCATE:
ADD DX,TYPE DTA ; No,then allocate room for new DTA
MOV CX,10H ; Search attribute
MOV AH,1AH
INT 21H
PUSH DX
MOV DX,OFFSET CG:PATH_NAME
MOV AH,4EH ; Call for "find first match"
INT 21H
POP DX
POP CX
RET
GET_FIRST_MATCH ENDP
GET_NEXT_MATCH PROC NEAR
PUSH CX
PUSH DX
MOV DX,OFFSET CG:PATH_NAME
MOV CX,10H
MOV AH,4FH
INT 21H
POP DX
POP CX
RET
GET_NEXT_MATCH ENDP
SEND_CRLF PROC NEAR
PUSH AX
PUSH DX
MOV AH,2
MOV DL,0AH
INT 21H
MOV DL,0DH
INT 21H
POP DX
POP AX
RET
SEND_CRLF ENDP
WRITE_STRING PROC NEAR
PUSH AX
PUSH DX
PUSH SI
CLD
MOV SI,DX
MOV AH,2
LODSB
WRITE_STRING_LOOP:
MOV DL,AL
INT 21H
LODSB
OR AL,AL ; End of string ?
JNZ WRITE_STRING_LOOP
POP SI
POP DX
POP AX
RET
WRITE_STRING ENDP
ERROR PROC NEAR
MOV AH,9
INT 21H
RET ; Print message
ERROR ENDP
DOS_EXIT PROC NEAR
MOV DL,[OLDDRIV]
MOV AH,0EH
INT 21H
MOV AH,4CH
INT 21H
DOS_EXIT ENDP
GET_CHAR_COUNT PROC NEAR
PUSH SI
MOV SI,DX
XOR CX,CX
CHAR_COUNT:
LODSB
CMP AL,' '
JBE CHAR_COUNT_RET
INC CX
JMP CHAR_COUNT
CHAR_COUNT_RET:
POP SI
RET
GET_CHAR_COUNT ENDP
PRINT_FILE_SEP PROC NEAR
PUSH DX
PUSH CX
MOV DX,OFFSET CRLF_STR
MOV AH,9
INT 21H
MOV DX,OFFSET SEARCH_NAME
CALL GET_CHAR_COUNT
PUSH CX
MOV BX,1
MOV AH,40H
INT 21H ; Print search name
POP CX ; How many characters in name ?
MOV DX,OFFSET FILE_SEP
ADD DX,CX
CALL ERROR
POP CX
POP DX
RET
PRINT_FILE_SEP ENDP
SCANOFF PROC NEAR
PUSH BX
PUSH CX
SCANOFF_CMP:
LODSB
CMP AL,' '
JBE SCANOFF_CMP
DEC SI
; Don't go beyond command line
MOV BX,80H
MOV CL,[BX]
XOR CH,CH
ADD CX,81H
CMP SI,CX
JB SCANOFF_RET
MOV SI,CX ; Point to end of command line
STC
POP CX
POP BX
RET
SCANOFF_RET:
CLC
POP CX
POP BX
RET
SCANOFF ENDP
NEXT_BLANK PROC NEAR
; Set SI to point to next blank character
LODSB
CMP AL,','
JA NEXT_BLANK
DEC SI
RET
NEXT_BLANK ENDP
INVALID_DRIVE DB 'Bad drive specified',13,10,'$'
NONAME DB 'No filename specified',13,10,'$'
WRONG_VERS DB 'MS-DOS must be at least version 2.0',13,10,'$'
FILE_SEP DB '---------------------------------------------',13,10,'$'
CRLF_STR DB 13,10,'$'
OLDDRIV DB 0
CURDRIVE DB 0
FIRST DB 0
LINCTR DB 0
PROMPT DB ' More ?',0AH,0DH,'$'
CMDLINE DW 81H
STAR_NAME DB '*.*',0
PATH_NAME DB '\',0
DB 80 DUP (0) ; space for 64 character pathname and 13 character filename
FILE_NAME DB 13 DUP (0)
SEARCH_NAME DB 13 DUP (0)
DISK_TRANSFER_AREAS LABEL BYTE
CODE_SEG ENDS
END START